#include "operate_image.h"
#include "widget.h"
#include <string>
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stb/stb_image_write.h>
#include <thread>

bool name_transfer_end = false;
std::thread * operate_image_thread = nullptr;

void operate_image(QString image_path_qs)
{
    name_transfer_end = false;
    if(operate_image_thread!=nullptr)
        delete operate_image_thread;
    operate_image_thread = new std::thread(_operate_image, &image_path_qs);
    operate_image_thread->detach();
    while (!name_transfer_end) {}
}


void _operate_image(QString * image_path_qs)
{
    main_widget->dp_message(QString("运行中..."), message_type::ordinary);

    std::string image_path_s = image_path_qs->toStdString();
    name_transfer_end = true;

    int width, height, channal;
    unsigned char * data = stbi_load(image_path_s.c_str(), &width, &height, &channal, 0);

    if (data==nullptr) {
        main_widget->dp_message(QString("文件打开失败TWT\n请检查权限或文件完整性"), message_type::warning);
        return;
    }

    bool is_encrypted = false;
    std::string postfix_name;
    int i=0;
    for (auto ptr = image_path_s.end()-1; ptr>=image_path_s.begin()-1; ptr--) {
        if (*ptr=='.') {
            if (i==0) {
                i++;
                postfix_name = std::string(ptr+1, image_path_s.end());
            }
            else {
                is_encrypted = true;
                postfix_name = std::string(ptr+1, image_path_s.end());
                break;
            }
        }
    }

    if (is_encrypted)
        _decrypt_image(image_path_s, data, width, height, channal);
    else
        _encrypt_image(image_path_s, data, width, height, channal);

    stbi_image_free(data);

    main_widget->clear_status();
}


void _encrypt_image(std::string image_path_s, unsigned char * data, int width, int height, int channal)
{
    int row_exchange_sum = height/2;
    int column_exchange_sum = width/2;

    for (int y=0; y<row_exchange_sum; y++) {
        if(y%20<10)
            continue;
        int i = data[y*width*channal+0*channal+0];
        unsigned char buffer[width*channal];
        for (int x=0; x<width; x++) {
            for (int channal_id=0; channal_id<channal; channal_id++) {
                int i = data[y*width*channal+x*channal+channal_id];
                buffer[x*channal+channal_id] = data[y*width*channal+x*channal+channal_id];
                data[y*width*channal+x*channal+channal_id] = data[(height-1-y)*width*channal+x*channal+channal_id];
                data[(height-1-y)*width*channal+x*channal+channal_id] = buffer[x*channal+channal_id];
            }
        }
    }

    for (int x=0; x<column_exchange_sum; x++) {
        if(x%20<10)
            continue;
        unsigned char buffer[height*channal];
        for (int y=0; y<height; y++) {
            for (int channal_id=0; channal_id<channal; channal_id++) {
                buffer[y*channal+channal_id] = data[y*width*channal+x*channal+channal_id];
                data[y*width*channal+x*channal+channal_id] = data[y*width*channal+(width-1-x)*channal+channal_id];
                data[y*width*channal+(width-1-x)*channal+channal_id] = buffer[y*channal+channal_id];
            }
        }
    }

    stbi_write_png((image_path_s+std::string(".encrypt.png")).c_str(), width, height, channal, data, 0);

    main_widget->dp_message(QString("加密图片完成^_^"), message_type::all_right);
}


void _decrypt_image(std::string image_path_s, unsigned char * data, int width, int height, int channal)
{
    int row_exchange_sum = height/2;
    int column_exchange_sum = width/2;

    for (int y=0; y<row_exchange_sum; y++) {
        if(y%20<10)
            continue;
        int i = data[y*width*channal+0*channal+0];
        unsigned char buffer[width*channal];
        for (int x=0; x<width; x++) {
            for (int channal_id=0; channal_id<channal; channal_id++) {
                int i = data[y*width*channal+x*channal+channal_id];
                buffer[x*channal+channal_id] = data[y*width*channal+x*channal+channal_id];
                data[y*width*channal+x*channal+channal_id] = data[(height-1-y)*width*channal+x*channal+channal_id];
                data[(height-1-y)*width*channal+x*channal+channal_id] = buffer[x*channal+channal_id];
            }
        }
    }

    for (int x=0; x<column_exchange_sum; x++) {
        if(x%20<10)
            continue;
        unsigned char buffer[height*channal];
        for (int y=0; y<height; y++) {
            for (int channal_id=0; channal_id<channal; channal_id++) {
                buffer[y*channal+channal_id] = data[y*width*channal+x*channal+channal_id];
                data[y*width*channal+x*channal+channal_id] = data[y*width*channal+(width-1-x)*channal+channal_id];
                data[y*width*channal+(width-1-x)*channal+channal_id] = buffer[y*channal+channal_id];
            }
        }
    }

    auto ptr = image_path_s.end()-1;
    int i=0;
    for (; ptr>=image_path_s.begin(); ptr--) {
        if (*ptr=='.') {
            if(i==0)
                i++;
            else
                break;
        }
    }
    stbi_write_png(std::string(image_path_s.begin(), ptr).c_str(), width, height, channal, data, 0);

    main_widget->dp_message(QString("解密图片完成^_^"), message_type::all_right);
}

void clear_up()
{
    if(operate_image_thread!=nullptr)
        delete operate_image_thread;
}
